#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QtGui>
#include <QtNetwork/QtNetwork>
#include <QtXml/QtXml>
#include <QtWebKit>
#include <QDebug>


#include <QtGui/QX11Info>
#include <X11/Xlib.h>
#include <X11/Xatom.h>


MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow),
        m_latitude(48.1142),
        m_longitude(-1.664),
        once(true),
        m_currentZoom(7)
{
    ui->setupUi(this);

    qRegisterMetaType<QObjectList>();

    /*

     METTRE TOUT LE JAVASCRIPT DANS LE FICHIER
     COMME CA MAPPY PEUT ETRE CHANGE PAR N'IMPORTE QUELLE API

     */

    QWebSettings* settings = QWebSettings::globalSettings();
    settings->setAttribute(QWebSettings::JavascriptEnabled, true);
    settings->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);


    connect(ui->webView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(injectJavascriptIntoWindowObject()));
    connect(ui->webView, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished(bool)));


    //ui->webView->load(QString("http://www.google.com"));



    QGeoPositionInfoSource *source = QGeoPositionInfoSource::createDefaultSource(this);
    if (source) {
        connect(source, SIGNAL(positionUpdated(QGeoPositionInfo)),
                this, SLOT(positionUpdated(QGeoPositionInfo)));
        source->startUpdates();
    }




    grabZoomKeys(true);

}

void MainWindow::grabZoomKeys(bool grab)
     {
         if (!winId()) {
             qWarning("Can't grab keys unless we have a window id");
             return;
         }

         unsigned long val = (grab) ? 1 : 0;
         Atom atom = XInternAtom(QX11Info::display(), "_HILDON_ZOOM_KEY_ATOM", False);
         if (!atom) {
             qWarning("Unable to obtain _HILDON_ZOOM_KEY_ATOM. This example will only work "
                      "on a Maemo 5 device!");
             return;
         }

         XChangeProperty (QX11Info::display(),
                 winId(),
                 atom,
                 XA_INTEGER,
                 32,
                 PropModeReplace,
                 reinterpret_cast<unsigned char *>(&val),
                 1);
     }

void MainWindow::keyPressEvent(QKeyEvent* event)
     {
         switch (event->key()) {
         case Qt::Key_F7: {
             qDebug() << "zoom in" << endl;

             //QMouseEvent fakeEvent(QEvent::MouseButtonDblClick, QPoint(10,10), Qt::LeftButton, 0, 0);
             //QApplication::sendEvent(ui->webView, &fakeEvent);

             QString javascript = QString("map.setZoomLevel(%1);").arg(++m_currentZoom);
             ui->webView->page()->mainFrame()->evaluateJavaScript(javascript);

             event->accept();
             break;
         }
         case Qt::Key_F8:
             qDebug() << "zoom out" << endl;
             QString javascript = QString("map.setZoomLevel(%1);").arg(--m_currentZoom);
             ui->webView->page()->mainFrame()->evaluateJavaScript(javascript);
             event->accept();
             break;
         }
         QWidget::keyPressEvent(event);
     }

void MainWindow::positionUpdated(const QGeoPositionInfo &info)
{
    // qDebug() << "Position updated:" << info;
    if (once) {

        // OU Mieux : source->stopUpdates()
        once = false;

    // for now use hardcoded value for rennes

    //m_latitude = info.coordinate().latitude();
    //m_longitude = info.coordinate().longitude();
    //ui->lineEdit->setText(QString::number(m_longitude));
    ui->webView->load(QString("qrc:/html/map.html"));
}
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::debug(const QString& value) {
    qDebug("%s", qPrintable(value));
}

void MainWindow::injectJavascriptIntoWindowObject() {
    qDebug() << "load qt object" << endl;
    ui->webView->page()->mainFrame()->addToJavaScriptWindowObject("monmanager", this);

}

void MainWindow::loadFinished(bool ok) {


    QFile file(QString(":/script/map.js"));
    if (file.open(QIODevice::ReadOnly)) {
        QString javascript = QString::fromUtf8(file.readAll());
        ui->webView->page()->mainFrame()->evaluateJavaScript(javascript);
    }

    emit displayUser(m_longitude, m_latitude);



/*
        QString javascript = "var map = new Mappy.api.map.Map({ container:'#mymap'});";
        javascript += QString("map.setCenter(new Mappy.api.geo.Coordinates(%1, %2),5);").arg(m_longitude).arg(m_latitude);
        ui->webView->page()->mainFrame()->evaluateJavaScript(javascript);
        */




    QNetworkAccessManager * manager = new QNetworkAccessManager(this);
    connect(manager, SIGNAL(finished(QNetworkReply*)), SLOT(dataReceived(QNetworkReply*)));

    QUrl url;
    url.setScheme("http");
    url.setEncodedHost("data.keolis-rennes.com");
    url.setEncodedPath("/xml/");
    url.addEncodedQueryItem("version", "1.0");
    url.addEncodedQueryItem("key", QString("JW48LBH2QN0A5M9").toAscii());
    url.addEncodedQueryItem("cmd", QString("getstation").toAscii());
    url.addEncodedQueryItem("param[request]", "proximity");
    url.addEncodedQueryItem("param[mode]", "coord");
    url.addEncodedQueryItem("param[lat]", QString::number(m_latitude).toAscii());
    url.addEncodedQueryItem("param[long]", QString::number(m_longitude).toAscii());

    //QUrl url(QString("http://data.keolis-rennes.com/xml/?version=1.0&key=%1&cmd=%2").arg("JW48LBH2QN0A5M9").arg("getstation"));
    QNetworkRequest request(url);
    manager->get(request);


}

void MainWindow::dataReceived(QNetworkReply* reply) {
    QDomDocument doc;
    if(doc.setContent(reply)) {
        //qDebug() << doc.toString();

#ifdef Q_WS_MAEMO_5
        setAttribute(Qt::WA_Maemo5AutoOrientation, true);
#endif

        // <opendata>
        QDomElement docElem = doc.documentElement();

        QDomNode nodeAnswer = docElem.namedItem("answer");
        if (!nodeAnswer.isNull()) {

            QDomNode nodeStatus = nodeAnswer.namedItem("status");

            if (!nodeStatus.isNull()) {

                QDomElement statusElem = nodeStatus.toElement();
                if (!statusElem.isNull()) {
                    qDebug() << "code erreur" << statusElem.attribute("code") << endl;
                    qDebug() << "message" << statusElem.attribute("message") << endl;
                }
            }

            /*
            QDomNode dataNode = docElem.namedItem("data");
             if (!dataNode.isNull()) {
                    dataNode.childNodes()
             }*/
        }

        QDomNodeList stations = docElem.elementsByTagName("station");
        QObjectList list;
        for(int i = 0; i < stations.size(); i++) {
            QDomElement station = stations.item(i).toElement();
            QString name = station.namedItem("name").toElement().text();

            float latitude = station.namedItem("latitude").toElement().text().toFloat();
            float longitude = station.namedItem("longitude").toElement().text().toFloat();
            int slotCount = station.namedItem("slotsavailable").toElement().text().toInt();
            int bikeCount = station.namedItem("bikesavailable").toElement().text().toInt();

            /*
            QString javascript;
            javascript += "var markerLayer = new Mappy.api.map.layer.MarkerLayer(40);";
            javascript += "map.addLayer(markerLayer);";
            javascript += "var icon = new Mappy.api.ui.Icon(Mappy.api.ui.Icon.DEFAULT);";
            javascript += QString("icon.label = '%1';").arg(name);
            javascript += QString("var marker = new Mappy.api.map.Marker(new Mappy.api.geo.Coordinates(%1, %2), icon);").arg(longitude).arg(latitude);
            javascript += "marker.addToolTip('This is marker A');";
            javascript += "marker.addToolTip('This is marker A');";
            javascript += "marker.addListener(\"click\", function () {";
            javascript += "marker.openPopUp('Informations about marker A.');});";
            javascript += "markerLayer.addMarker(marker);";
            ui->webView->page()->mainFrame()->evaluateJavaScript(javascript);
            */
            Station *s= new Station(name, longitude, latitude, slotCount, bikeCount);
            m_stations.append(s);
            list.append(s);
            //emit addMarker(longitude, latitude);
            //emit addStations(m_stations);
        }
        emit addStations(list);
    }
}

QObjectList MainWindow::stations() const {


    //QVariantList list;
    QObjectList list;
    foreach(Station* s, m_stations) {
        //list.append(QVariant::fromValue(s));
        list.append(s);
    }

    return list;
}
